<template>
  <div class="menu-container">
    <el-row :gutter="10">
      <el-col :span="6" class="menu-panel">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>菜单管理</span>
          </div>
          <div class="menu-tree">
            <el-tree
              :style="{ marginTop: '2px' }"
              :props="defaultProps"
              :data="treeData"
              ref="treeNode"
              :default-expanded-keys="defaultExpand"
              highlight-current
              node-key="menuId"
              :expand-on-click-node="false"
              :render-content="renderContent"
              @node-click="nodeClick"
            ></el-tree>
            <Dialog
              ref="editDialog"
              :title="editDialogInfo.title"
              :buttons="editDialogInfo.buttons"
              :visible="editDialogInfo.show"
              @close="editDialogInfo.show = false"
            >
              <el-form
                ref="editForm"
                :model="formData"
                :rules="rules"
                label-width="100px"
              >
                <el-form-item label="菜单名称" prop="menuName" size="small">
                  <el-input :maxLength="20" v-model="formData.menuName" />
                </el-form-item>
                <el-form-item label="父级菜单" prop="pId" size="small">
                  <el-cascader
                    size="small"
                    filterable
                    :key="new Date().getTime()"
                    ref="pNodeCascader"
                    :style="{ width: '100%' }"
                    :props="defaultProps"
                    v-model="formData.pId"
                    :options="treeData"
                    @change="selectPNode"
                  ></el-cascader>
                </el-form-item>
                <el-form-item label="菜单类型" prop="menuType" size="small">
                  <el-radio v-model="formData.menuType" :label="0"
                    >菜单</el-radio
                  >
                  <el-radio v-model="formData.menuType" :label="1"
                    >按钮</el-radio
                  >
                </el-form-item>
                <el-form-item
                  label="请求路径"
                  prop="menuUrl"
                  size="small"
                  :rules="
                    formData.menuType == 0
                      ? [{ required: true, message: '请输入菜单路径' }]
                      : []
                  "
                >
                  <el-input
                    :maxLength="50"
                    v-model="formData.menuUrl"
                    placeholder="eg:/settings/user"
                  />
                </el-form-item>
                <el-form-item
                  label="权限编码"
                  prop="permissionCode"
                  size="small"
                >
                  <el-select
                    v-model="formData.permissionCode"
                    placeholder="请选择权限编码"
                    filterable
                  >
                    <el-option
                      v-for="item in permissionCodeList"
                      :key="item.value"
                      :label="item.text"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="菜单图标" prop="icon" size="small">
                  <el-input
                    v-model="formData.icon"
                    :maxLength="10"
                    placeholder="eg:settings"
                  />
                </el-form-item>
                <el-form-item label="排序" prop="sort" size="small">
                  <el-input v-model="formData.sort" :maxLength="10" />
                </el-form-item>
              </el-form>
            </Dialog>
          </div>
        </el-card>
      </el-col>
      <el-col :span="18" class="menu-panel">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>菜单详情</span>
          </div>
          <el-form :model="detailData" label-width="100px" class="detail-form">
            <el-form-item label="菜单ID：">
              {{ detailData.menuId }}
            </el-form-item>
            <el-form-item label="菜单名称：">
              {{ detailData.menuName }}
            </el-form-item>
            <el-form-item label="菜单层级：">
              <el-breadcrumb
                separator-class="el-icon-arrow-right"
                :style="{ 'line-height': '40px' }"
              >
                <el-breadcrumb-item
                  v-for="(item, index) in detailData.level"
                  :key="index"
                  >{{ item }}</el-breadcrumb-item
                >
              </el-breadcrumb>
            </el-form-item>
            <el-form-item label="菜单类型：">
              {{ detailData.menuTypeName }}
            </el-form-item>
            <el-form-item label="请求路径：">
              {{ detailData.menuUrl }}
            </el-form-item>
            <el-form-item label="权限编码：">
              {{ detailData.permissionCode }}
            </el-form-item>
            <el-form-item label="菜单图标：">
              <span :class="'iconfont icon-' + detailData.icon"></span>
            </el-form-item>
            <el-form-item label="排序号：">
              {{ detailData.sort }}
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>
<script>
export default {
  props: {
    showEdit: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      defaultProps: {
        children: 'children',
        label: 'menuName',
        value: 'menuId',
        key: 'menuId',
        title: 'menuName',
        checkStrictly: true,
        expandTrigger: 'hover',
      },
      formData: {
        pId: 0,
        sort: 0,
      },
      rules: {
        menuName: [{ required: true, message: '请输入名称' }],
        pId: [{ required: true, message: '请选择父级菜单' }],
        menuType: [{ required: true, message: '请选择菜单类型' }],
        permissionCode: [{ required: true, message: '请输入权限编码' }],
        sort: [
          {
            required: true,
            message: '请输入排序号',
          },
          {
            validator: this.Verify.number,
            trigger: 'blur',
            message: '请输入正确的排序号',
          },
        ],
      },
      editDialogInfo: {
        title: '新增菜单',
        show: false,
        buttons: [
          {
            type: 'primary',
            text: '确定',
            click: (e) => {
              this.submitForm(e)
            },
          },
        ],
      },
      api: {
        loadMenu: 'settings/menuList',
        saveMenu: 'settings/saveMenu',
        delMenu: 'settings/delMenu',
        permissionCodeList: 'settings/permissionCodeList',
      },
      treeData: [],
      detailData: {},
      permissionCodeList: [],
      defaultExpand: [],
      curOpMenuId: undefined,
    }
  },
  beforeCreate() {},
  methods: {
    getNodeLevel(node, level) {
      if (node.data.menuName) {
        level.unshift(node.data.menuName)
      }
      if (node.parent) {
        this.getNodeLevel(node.parent, level)
      }
    },
    nodeClick(data, node, cur) {
      let level = []
      this.getNodeLevel(node, level)
      this.detailData = data
      this.detailData.level = level
    },
    //渲染，新增，修改，删除按钮
    renderContent(h, { node, data, store }) {
      return (
        <span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px;">
          <span class="g-ellipsis" title={node.label}>
            {node.label}
          </span>
          <el-dropdown
            trigger="click"
            class="tree-op"
            nativeOnClick={(event) => event.stopPropagation()}
          >
            <span class="iconfont icon-more"></span>
            <el-dropdown-menu slot="dropdown">
              {data.pId !== -1 ? (
                <el-dropdown-item
                  nativeOnClick={() => this.showEditDialog('edit', data)}
                >
                  编辑菜单
                </el-dropdown-item>
              ) : null}
              <el-dropdown-item
                nativeOnClick={() => this.showEditDialog('add', data)}
              >
                添加子菜单
              </el-dropdown-item>
              {data.pId !== -1 ? (
                <el-dropdown-item nativeOnClick={() => this.delMenu(data)}>
                  删除
                </el-dropdown-item>
              ) : null}
            </el-dropdown-menu>
          </el-dropdown>
        </span>
      )
    },
    selectPNode(value) {
      this.$refs.pNodeCascader.dropDownVisible = false
    },
    //提交
    async submitForm(e) {
      e.preventDefault()
      this.$refs.editForm.validate(async (valid) => {
        if (!valid) {
          return false
        }
        let pId = this.formData.pId
        if (typeof pId == 'object') {
          pId = pId[pId.length - 1]
        }
        let params = {
          menuName: this.formData.menuName,
          pId: pId,
          menuType: this.formData.menuType,
          menuUrl: this.formData.menuUrl,
          permissionCode: this.formData.permissionCode,
          icon: this.formData.icon,
          sort: this.formData.sort,
          menuId: this.formData.menuId,
        }
        await this.Request({
          url: this.api.saveMenu,
          params: params,
        })
        this.$refs.editDialog.close()
        this.$message.success('保存成功')
        this.loadMenu()
      })
    },
    //删除
    delMenu(data) {
      this.curOpMenuId = data.pId
      this.$confirm(`确定要删除【${data.menuName}】吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(async () => {
          await this.Request({
            url: this.api.delMenu,
            params: {
              menuId: data.menuId,
            },
          })
          this.$message.success('删除成功')
          this.loadMenu()
        })
        .catch(() => {})
    },
    //展示弹出框
    async showEditDialog(type, data) {
      this.curOpMenuId = data.menuId == undefined ? data.pId : data.menuId

      this.editDialogInfo.show = true

      let permissionCodeList = await this.Request({
        url: this.api.permissionCodeList,
      })
      this.permissionCodeList = permissionCodeList
      this.$nextTick(async () => {
        if (this.$refs['editForm']) {
          this.$refs['editForm'].resetFields()
        }
        if (type === 'edit') {
          this.editDialogInfo.title = '修改菜单'
          this.formData = Object.assign({}, data)
        } else {
          this.editDialogInfo.title = '新增菜单'
          let sort = data.children ? data.children.length + 1 : 1
          this.formData = {
            pId: data.menuId,
            sort: sort,
          }
        }
      })
    },
    //加载菜单
    async loadMenu() {
      let menuList = await this.Request({
        url: this.api.loadMenu,
      })
      this.treeData = menuList

      let expandIds = []
      menuList[0].children.forEach((element) => {
        expandIds.push(element.menuId)
      })
      if (this.curOpMenuId) {
        expandIds.push(this.curOpMenuId)
      }
      this.defaultExpand = expandIds
    },
  },
  created() {
    this.loadMenu()
  },
}
</script>
<style lang="less">
.menu-container {
  overflow: hidden;
  .menu-tree {
    width: 100%;
    max-height: calc(~'100vh - 210px');
    overflow: auto;
    margin-top: 5px;
    .icon-users {
      padding-right: 5px;
      float: left;
    }

    .el-tree-node__content {
      display: block;
      line-height: 30px;
      height: 30px;
      .el-tree-node__expand-icon {
        float: left;
        margin-top: 5px;
      }
    }
    .g-ellipsis {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 240px;
      display: inline-block;
    }

    .tree-op {
      float: right;
      margin-top: 0px;
      .iconfont {
        font-size: 20px;
      }
      .iconfont:hover {
        font-size: 20px;
        color: rgb(51, 112, 255);
      }
    }
  }
}
</style>
